﻿

#查询端口占用方法
function PortName([string] $port){ 
    get-childitem IIS:\sites | foreach-object{
        $site=$_;
        $bindingTokens=$site.bindings.collection.bindinginformation -split':';
        if($bindingTokens[1] -eq $port){
            return $site.name
        }
    }
}

#创建主站点
function CreateMainWeb(){
    Param(
		[parameter(Mandatory=$true)]
		[String]$Path = "",   #主站点根目录
        [parameter(Mandatory=$true)]
        [string]$name = '', #主站点名称
        [parameter(Mandatory=$true)]
        [string]$post = '', #主站点名称
        [parameter(Mandatory=$true)] #主站点解压目录
        [string]$UnzipPath = ''
	)
    #判断站点目录是否存在  不存在则创建
    if(test-path $Path\$name\$UnzipPath){}else{mkdir $Path\$name\$UnzipPath;}
    #信息提示
    Write-Verbose -Verbose '主站点创建';
    # 创建站点
     New-Item IIS:\Sites\$name -Bindings @{protocol='http';bindingInformation='*:'+$post+':'} -PhysicalPath $Path\$name\$UnzipPath

     if(GetAppPools -AppPoolName $name){
        Write-Verbose -Verbose $name'应用程序池已存在';
     }else{
         # 创建站点应用程序池
         new-item AppPools\$name 
     }
     # 修改站点应用程序池绑定
     Set-ItemProperty -path IIS:\Sites\$name -name applicationPool -value $name
    #信息提示
    Write-Verbose -Verbose '主站点创建完毕';
}

#创建应用程序
function CreateApplication(){
    Param(
		[parameter(Mandatory=$true)]
		[String]$path = "",   #主站点根目录
		[parameter(Mandatory=$true)]
		[String]$parentName = "",   #主站点名称
        [parameter(Mandatory=$true)]
        [string]$name = '' #应用程序名称
	)

    #开始信息提示
    Write-Verbose -Verbose $name'应用程序创建';
    #创建文件夹
    if(test-path $path\$parentName\$name){}else{mkdir $path\$parentName\$name;}
    # 在站点下创建应用程序
    new-item iis:\sites\$parentName\$name -type Application -physicalpath $path\$parentName\$name; 
    if(GetAppPools -AppPoolName $name){
        Write-Verbose -Verbose $name'应用程序池已存在';
    }else{
        # 创建站点应用程序池
         new-item AppPools\$name
     }
     # 修改站点下应用程序 的 应用程序池绑定
     Set-ItemProperty -path IIS:\Sites\$parentName\$name -name applicationPool -value $name;
    #结束信息提示
    Write-Verbose -Verbose $name'应用程序创建';
}

#查询应用程序池是否存在
function GetAppPools{
    
    Param(
		[parameter(Mandatory=$true)]
		[String]$AppPoolName = ""   #主站点根目录
	)

    cd AppPools;
    $pools=ls;
    foreach($item in $pools){
        if($item.Name -eq $AppPoolName){
            cd..
            return $true;
        }
    }
    cd..
}

#检查站点是否存在
function GetSite()
{
    Param(
            [parameter(Mandatory=$true)]
            [string]$siteName = '' #站点名称
	    )
    try
    {
        $site = Get-Item "IIS:\Sites\$siteName" -ErrorAction Stop
        return $site
    }catch [System.SystemException]
    {
        #Write-Host -foregroundColor "Red" "获取站点 $siteName 信息失败"
        return $null
    }
}


#检查应用程序是否存在
function GetApplication()
{
    Param
    (
         [parameter(Mandatory=$true)]
         [string]$siteName = '', #站点名称
         [parameter(Mandatory=$true)]
         [string]$appName = '' #应用程序名称
	 )
    if(GetSite $siteName)
    {
        try
        {
            $app = Get-Item "IIS:\Sites\$siteName\$appName" -ErrorAction Stop
            return $app
        }catch [System.SystemException]
        {
            #Write-Host -foregroundColor "Red" "获取应用程序 $appName 失败"
            return $null
        }
    }
}

#主站点绑定路径
function GetMainWebAddress(){
    
    Param(
		[parameter(Mandatory=$true)]
		[String]$parentName = ""  #主站点名称
	)

    Get-childitem IIS:\Sites|ForEach-Object{
        $obj=$_;
        if($obj.Name -eq $parentName){
            return $obj.PhysicalPath;
        }
    }
}
#获取应用程序绑定路径
function GetApplicationAddress(){

    Param(
		[parameter(Mandatory=$true)]
		[String]$parentName = "",   #主站点名称
        [parameter(Mandatory=$true)]
        [string]$name = '' #应用程序名称
	)
     get-childitem IIS:\sites\$parentName | foreach-object{
        $app=$_;
        if($app.Name -eq $name){
            return $app.PhysicalPath;
        }
     } 
}

#解压文件
Function Unzip-File()
{
    param(
        [parameter(Mandatory=$true)]
        [string]$ZipFile,    #要解压的文件路径
        [parameter(Mandatory=$true)]
        [string]$TargetFolder  #解压目录
    )

    #确保目标文件夹必须存在
    if(!(Test-Path $TargetFolder))
    {
        mkdir $TargetFolder
    }
    if(Test-Path $ZipFile){
        $fileHou=$ZipFile.Split('.')[$ZipFile.Split('.').Length-1];
        if($fileHou -eq "zip"){
            $shellApp = New-Object -ComObject Shell.Application;
            $files = $shellApp.NameSpace($ZipFile).Items();
            #下面这句会删除已解压的文件和本地文件相同的本地文件，但不会影响目录内其它不相干的文件      
            #$files|%{Remove-Item ("$TargetFolder/{0}" -f  $_.name ) -Force -Recurse}
            #.CopyHere($files,16); 参数16 回答“是所有”的任何对话框。
            $shellApp.NameSpace($TargetFolder).CopyHere($files,16);
        }else{
            $host.ui.WriteErrorLine("无法解压"+$fileHou+"格式文件，仅支持解压zip文件。")
        }
    }else{
        $host.ui.WriteErrorLine($ZipFile+"找不到要解压的文件,解压失败。")
    }
}

#下载文件并解压
function UpLoadAndUnzip(){

    param(
        [parameter(Mandatory=$true)]
        [string]$webSiteName,    #主站点名称
        [parameter(Mandatory=$true)]
        [string]$name,            #应用程序名称
        [parameter(Mandatory=$true)]
        [string]$uploadPath       #应用程序绑定路径
    )

    #查询目录下最新文件
    $fileName=GetNewWcfFile $name;

    #文件下载  wcf服务
    if((DownWcfFile -Path $name\$fileName -LocalPath $uploadPath\$fileName  -ErrorAction "SilentlyContinue") -eq $true){
        Write-Verbose -Verbose '解压文件';
        #解压文件  如果有最新文件则进行解压
        Unzip-File -ZipFile $uploadPath\$fileName -TargetFolder $uploadPath;
        #删除旧版本文件
        RemoveFile -uploadPath $uploadPath -FileName $fileName;
        Write-Verbose -Verbose $name'文件跟新完毕';
    }else{
        Write-Verbose -Verbose $name"的文件是最新版";
    }
}

#查询目录下文件的最新版本
function GetNewWcfFile(){
    
    Param(
		[parameter(Mandatory=$true)]
		[String]$Path = ""
	)

    [int] $No=0;
    $fileName="";
    
    #遍历FTP目录下的文件 倒序排列 取最新修改的文件
    Get-FTPChildItem  -Path $Path | Sort-Object -Property ModifiedDate -Descending | ForEach-Object{ 
        $obj=$_; 
        
        $No=$No+1;
        if($No -eq 1){
            return $obj.Name
        }
    }
}
#删除本地旧文件
function RemoveFile(){
    Param(
		[parameter(Mandatory=$true)]
        [string]$FileName,      #新文件名称
        [parameter(Mandatory=$true)]
        [string]$uploadPath       #应用程序绑定路径
	)
    #获取文件夹下所有zip文件
    #Get-ChildItem d:\ -Include *.txt -recurse #-Recurse 表示是否循环遍历子目录，而-Include表示筛选条件
    $localFile=get-childitem -Path $uploadPath -ErrorAction SilentlyContinue -Filter *.zip;
    foreach($file in $localFile.Name){
        if($FileName -ne $file){
            #删除旧文件
            rm $uploadPath\$file;
        }
    }
}
#下载文件
function DownWcfFile(){
    
    Param(
		[parameter(Mandatory=$true)]
		[String]$Path = "",   #FTP下载路径（含文件名）
        [parameter(Mandatory=$true)]
        [string]$LocalPath='' #文件下载路径（含文件名）
	)

    Write-Verbose -Verbose '检查下载文件信息';
    if(test-path $LocalPath){
        #"文件存在,已是最新版本";
        return $false;
    }else{
        Write-Verbose -Verbose '开始下载最新版本文件';
        Get-FTPItem  -Path $Path -LocalPath $LocalPath;
        Trap
        {
            $host.UI.WriteErrorLine("下载文件发生异常，DownWcfFile方法中Get-FTPItem异常");
            Write-Verbose -Verbose ("参数：Path："+$Path+",LocalPath："+$LocalPath);
            #中断脚本
            break
        }
        return $true;
    }
}


#右下角气球弹窗提示
function BalloonMessage(){
    #加载 Winform 程序集,使用Out-Null抑制输出
    [system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
 
    #创建 NotifyIcon 对象
    $balloon = New-Object System.Windows.Forms.NotifyIcon
    $path = Get-Process -id $pid | Select-Object -ExpandProperty Path
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
    $balloon.Icon = $icon
    $balloon.BalloonTipIcon = 'Info'
    $balloon.BalloonTipText = '脚本执行完毕'
    $balloon.BalloonTipTitle = 'PowerShell tips'
    $balloon.Visible = $true
 
    #显示气球提示框
    $balloon.ShowBalloonTip(10000)
}


#格式化处理输入主站点根目录 目录结尾不要'\'
function PathChange([string] $inPath){
    $outPath="";
    $No=1;
    foreach($path in $inPath.Split('\')){
        if($No -eq 1){
            $outPath=$path;
        }else{
            if($path -ne ""){
                $outPath=$outPath+"\"+$path;
            }
        }
        $No++;
    }
    return $outPath;
}
